/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nageoffer.shortlink.admin.common.biz.user;

import cn.hutool.core.util.StrUtil;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

/**
 * 用户信息传输过滤器
 */
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {

    /**
     * 执行过滤操作，将用户信息存储在用户上下文中
     * 此过滤器旨在从HTTP请求中提取用户信息，并将其存储在用户上下文中，以便在后续处理中使用
     * 如果请求中提供了用户名、用户ID和真实姓名，这些信息将被封装到UserInfoDTO对象中，并通过UserContext.setUser方法存储
     * 在过滤链完成后，无论是否成功，都会移除用户上下文中的信息，以避免内存泄漏
     *
     * @param servletRequest Servlet请求对象，用于获取请求头中的用户信息
     * @param servletResponse Servlet响应对象，未在此方法中直接使用
     * @param filterChain 过滤链对象，用于将控制权传递给下一个过滤器或目标资源
     */
    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
        // 将Servlet请求转换为HttpServletRequest，以便访问请求头信息
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        // 从请求头中获取用户名
        String username = httpServletRequest.getHeader("username");
        // 如果用户名不为空，则继续处理用户信息
        if (StrUtil.isNotBlank(username)) {
            // 从请求头中获取用户ID和真实姓名
            String userId = httpServletRequest.getHeader("userId");
            String realName = httpServletRequest.getHeader("realName");
            // 创建UserInfoDTO对象，封装用户信息
            UserInfoDTO userInfoDTO = new UserInfoDTO(userId, username, realName);
            // 将用户信息存储在用户上下文中
            UserContext.setUser(userInfoDTO);
        }
        // 尝试执行过滤链中的下一个过滤器或目标资源
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            // 无论如何，最后移除用户上下文中的信息，以避免内存泄漏
            UserContext.removeUser();
        }
    }
}